package jp.co.iris_ltd.irisphotoeditor;

import java.util.HashMap;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;

public class ImageContentsListAdapter extends BaseAdapter {

    private class ImageLoaderTaskHelper extends AsyncTask<String, Void, Bitmap> {

        private ImageView mView;

        public ImageLoaderTaskHelper(ImageView view) {
            mView = view;
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            return getImageBitmap(params[0]);
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            if (result != null) {
                mView.setImageBitmap(result);
            } else {
                mView.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_menu_filter));
            }
        }
    }

    private class ItemViewHolder {
        ImageView icon;
        TextView title;
        ImageLoaderTaskHelper loader;
    }

    private HashMap<Integer, String> mUriMap;
    private int MAX;
    private Context mContext;
    private LayoutInflater mLayoutInflater;
    private LruCache<String, Bitmap> mMemoryCache;
    private Drawable mProvisionalImage;

    public ImageContentsListAdapter(Context context, ContentResolver cr, HashMap<Integer, String> hm, int max) {
        mContext = context;
        mUriMap = hm;
        MAX = max;
        mLayoutInflater = ((Activity) context).getLayoutInflater();
        mProvisionalImage = context.getResources().getDrawable(R.drawable.ic_menu_filter);

        final int memClass = ((ActivityManager) ((Activity) context).getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
        final int cacheSize = 1024 * 1024 * memClass / 8;
        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getRowBytes() * bitmap.getHeight();
            }
        };
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ItemViewHolder holder;
        if (convertView == null) {
            convertView = mLayoutInflater.inflate(R.layout.list_item_with_icon, null);
            holder = new ItemViewHolder();
            holder.icon = (ImageView) convertView.findViewById(R.id.image);
            holder.title = (TextView) convertView.findViewById(R.id.name);
            convertView.setTag(holder);
            convertView.setLayoutParams(new GridView.LayoutParams(100, 100));
        } else {
            holder = (ItemViewHolder) convertView.getTag();
            holder.icon.setImageDrawable(mProvisionalImage);
            if (holder.loader != null && !holder.loader.isCancelled()) {
                holder.loader.cancel(true);
                holder.loader = null;
            }
        }
        holder.title.setVisibility(View.GONE);

        String path = mUriMap.get(position);
        Bitmap cache = mMemoryCache.get(path);
        if (cache != null) {
            holder.icon.setImageBitmap(cache);
        } else {
            holder.loader = new ImageLoaderTaskHelper(holder.icon);
            holder.loader.execute(mUriMap.get(position));
        }

        return convertView;
    }

    private Bitmap getImageBitmap(String path) {
        Bitmap bmp = mMemoryCache.get(path);
        if (bmp == null) {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;

            BitmapFactory.decodeFile(path, options);
            int scaleW = options.outWidth / 64;
            int scaleH = options.outHeight / 64;

            int scale = Math.max(scaleW, scaleH);
            options.inJustDecodeBounds = false;
            options.inSampleSize = scale;
            bmp = BitmapFactory.decodeFile(path, options);

            if (path != null && bmp != null) {
                mMemoryCache.put(path, bmp);
            }
        }

        return bmp;
    }

    public final int getCount() {
        return MAX;
    }

    public final Object getItem(int position) {
        return mUriMap.get(position);
    }

    public final long getItemId(int position) {
        return position;
    }

}
